package com.stormrage.edu.serv.acct.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.shiro.authz.permission.WildcardPermission;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import com.stormrage.constants.ErrCons;
import com.stormrage.edu.dao.ent.EntAcctDao;
import com.stormrage.edu.serv.acct.EntAcctServ;
import com.stormrage.edu.serv.acct.EntResServ;
import com.stormrage.edu.serv.ent.EntEnterpriseServ;
import com.stormrage.entity.ent.EntAcct;
import com.stormrage.entity.ent.EntEnterprise;
import com.stormrage.entity.ent.EntRes;
import com.stormrage.entity.ent.req.EntAcctReq;
import com.stormragetech.core.exception.StormrageTechException;
import com.stormragetech.core.util.SecureUtil;

/**
 * @author www.stormragetech.com
 * @date 2016年1月19日
 * @version 1.0.0
 */
@Service
public class EntAcctServImpl implements EntAcctServ {

	private static final Logger logger = LoggerFactory.getLogger(EntAcctServImpl.class);

	@Autowired
	private EntAcctDao acctDao;

	@Autowired
	private EntResServ resServ;

	@Autowired
	private EntEnterpriseServ entEnterpriseServ;

	@Override
	public Integer create(EntAcctReq arg0) throws StormrageTechException {

		logger.debug(" 【 Serv 】- 【 EntAcctServ 】- 【 Create 】- 开始运行 ");

		// ------------------ 验证用户名是否重复 ------------------
		Boolean b = isExist(arg0.getAcct());
		if (b) {
			throw StormrageTechException.instance(ErrCons.SERV_ERR, "用户名已存在", StormrageTechException.ERR_APP,
					"【 EntAcctServ 】-【 Create 】");
		}

		// ------------------ 创建管理员 ------------------
		EntAcct acct = EntAcct.instance(arg0.getAcct(), arg0.getPass(), arg0.getEntId(), arg0.getRealName());
		Integer index = acctDao.create(acct);

		// ------------------ 修改公司资料 ------------------
		EntEnterprise ent = entEnterpriseServ.queryById(arg0.getEntId());
		ent = EntEnterprise.instance(ent, arg0.getPhone(), arg0.getEmail());
		entEnterpriseServ.update(ent);

		logger.debug(" 【 Serv 】- 【 EntAcctServ 】- 【 Create 】- 结束运行 ");
		return index;

	}

	@Override
	public void updatePass(final EntAcctReq arg0) throws StormrageTechException {

		// ------------------ 获取管理员详细信息 ------------------
		EntAcct acct = queryByAcctLock(arg0.getAcct());
		if (null == acct) {
			throw StormrageTechException.instance(ErrCons.SERV_ERR, "用户名不存在", StormrageTechException.ERR_APP,
					"【 EntAcctServ 】-【 UpdatePass 】");
		}
		acct.setPass(arg0.getPass());
		acct.setSalt(SecureUtil.initUUID());
		acct.setPass(SecureUtil.initPass(acct.getPass(), acct.getSign()));
		logger.debug(" 修改密码的原材料为 " + acct.toString());

		// ------------------ 修改用户密码 ------------------
		acctDao.updatePass(acct);
	}

	@Override
	public EntAcct queryById(Integer arg0) throws StormrageTechException {
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("id", arg0);
		EntAcct entity = acctDao.queryById(map);
		logger.debug(" - 查询结果为 -" + entity);
		return entity;
	}

	@Override
	public EntAcct queryByAcct(String arg0) throws StormrageTechException {
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("acct", arg0);
		EntAcct acct = acctDao.queryByAcct(map);
		logger.debug(" - 查询结构为 - " + acct);
		return acct;
	}

	@Override
	public EntAcct queryByAcctLock(final String arg0) throws StormrageTechException {
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("acct", arg0);
		map.put("locked", 0);
		EntAcct acct = acctDao.queryByAcctLock(map);
		logger.debug(" - 查询结构为 - " + acct);
		return acct;
	}

	@Override
	public Set<String> queryPermSet() throws StormrageTechException {

		Set<String> perms = new HashSet<String>();

		List<EntRes> resList = resServ.queryList();
		for (EntRes res : resList) {
			perms.add(res.getPermission());
		}

		logger.debug(" 用户权限列表为 " + perms.toString());

		return perms;

	}

	@Override
	public Set<String> queryPermSetById(Integer arg0) throws StormrageTechException {

		Set<String> perms = new HashSet<String>();

		List<EntRes> resList = resServ.queryListByAcctId(arg0);
		for (EntRes res : resList) {
			perms.add(res.getPermission());
		}

		logger.debug(" 用户权限列表为 " + perms.toString());

		return perms;

	}

	@Override
	public List<EntRes> queryMenuById(Integer arg0) throws StormrageTechException {

		Set<String> perms = null;

		perms = queryPermSet();

		List<EntRes> menus = new ArrayList<EntRes>();

		List<EntRes> resList = resServ.queryListByTypeParent("menu", 0);
		for (EntRes res : resList) {
			if (!hasPerm(perms, res))
				continue;
			List<EntRes> children = resServ.queryListByTypeParent("menu", res.getId());
			if (null != children && children.size() > 0) {
				for (EntRes child : children) {
					if (!hasPerm(perms, res)) {
						children.remove(child);
					}
				}
				res.setChildren(children);
			}
			menus.add(res);
		}

		logger.debug(" 用户的menu为 " + menus.toString());

		return menus;

	}

	private Boolean isExist(String arg0) throws StormrageTechException {

		Boolean rs = Boolean.TRUE;

		EntAcct entity = queryByAcct(arg0);
		if (null == entity)
			rs = Boolean.FALSE;

		return rs;

	}

	private boolean hasPerm(Set<String> arg0, EntRes arg1) {

		if (StringUtils.isEmpty(arg1.getPermission())) {
			return true;
		}
		for (String permission : arg0) {
			WildcardPermission p1 = new WildcardPermission(permission);
			WildcardPermission p2 = new WildcardPermission(arg1.getPermission());
			if (p1.implies(p2) || p2.implies(p1)) {
				return true;
			}
		}
		return false;
	}

}
